<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>MySuiteA API Overview</title>

    <style>
     body {
       box-sizing:   border-box;
       width:        calc(384px + 40vw);
       margin:   1em calc(30vw - 192px);
       padding:  2ex;
     }

     table {
       border-collapse:  collapse;
     }

     /* body > table {
        width:    100%;
        } */

     th, td {
       padding:  3pt;
     }

     th {
       border:   thin solid black;
     }

     td {
       border:   thin solid gray;
     }

     code, pre {
       background:   silver;
       background:   rgba(224,224,224,0.75);
     }

     pre {
       white-space:  pre-line;
     }

     span.tab {
       display:      inline-block;
       width:        4ex;
     }

     .math-fonts {
       white-space:  nowrap;
       font-family:  serif;
     }

     .math-fonts var {
       font-size:    125%;
     }
    </style>

  </head>
  <body>

    <h1>MySuiteA's View of Cryptogrpahy Algorithms</h1>

    <p>
      In MySuiteA's view, a cryptographic algorithm consist of a set of
      functions that transforms operands between various forms such as
      plaintext message, ciphertext, digest, signature, predicate,
      and/or other form of information;
    </p>

    <p>
      a cryptographic algorithm is
      associated with a set of properties that are intrinsic of the algorithm
      (e.g. key and key schedule size, output size, input length limit);
    </p>

    <p>
      an algorithm may be based on another algorithm, a.k.a. an algorithm
      is parameterized by another (set of) algorithm(s) - for example, a
      digital signature may be instantiated with a hash function, an
      encryption algorithm may be instantiated with a blockcipher, etc.
    </p>

    <p>
      Based on the above premise, the term <em>algorithm construction</em>
      refers to algorithms that needs to be instantiated with another (set of)
      algorithm(s) or other types of parameters; the term <em>algorithm
      instance</em> refers to algorithms which have all necessary
      parameterizations (if any) specified and can operate on operands in a
      definite way.
    </p>

    <p>
      The term <em>algorithm</em> can refer to either <em>algorithm
      construction</em> or <em>algorithm instance</em>. The term
      <em>algorithm family</em> is banned from use in MySuiteA documentations
      as it is ambiguous.
    </p>

    <h1>MySuiteA's Implementation of Algorithms</h1>

    <h2>Algorithm Instances</h2>

    <p>
      MySuiteA implements a uniform interface for using and instantiating from
      cryptographic algorithms at compile, link, and run time.
    </p>

    <p>
      At compile time, a function-like macro whose name consists of the name
      of the algorithm prefixed with a single lower-case letter "c" is defined.
      This macro takes a single argument <code><var>q</var></code>, which
      specifies the property associated with the algorithm to be queried, and
      evaluates to the value of that property.
      For other queries, this macro evaluates to 0.
    </p>

    <p>
      At link time, a similar macro exists. In addition to the queries
      available in the compile time queries, the pointers to the set of
      functions constituting the algorithm may be queried.
      The prefix of this macro is "x" instead of "c".
    </p>

    <p>
      At run time, a function with the exact behavior of the link time macro
      exists. A function is needed so as to enable run-time instantiation,
      as a function can be encapsulated in a pointer to the function.
      Such a function is colloquially called a "crypto object".
    </p>

    <p>
      For the set of queries available (and their applicability to particular
      types of algorithm), see "mysuitea-common.h".
    </p>

    <h2>Algorithm Construction Instantiation at Run Time</h2>

    <p>
      The "crypto object" function mentioned above takes a single argument.
      It has the prototype:
    </p>

    <pre>
      IntPtr (*iCryptoObj_t)(int q);
    </pre>

    <p>
      where <code>IntPtr</code> is a signed integer type with same width as
      a pointer type. By default this is defined to be the same as
      <code>intptr_t</code>, however on systems where object and function
      pointer types have different representation, this may be changed to
      something else by the user of the MySuiteA library.
    </p>

    <p>
      A algorithm construction crypto object is represented as a function that
      takes a parameterization argument first, then the query. Such function
      has the prototype:
    </p>

    <pre>
      IntPtr (*tCryptoObj_t)(const CryptoParam_t *P, int q);
    </pre>

    <p>
      where <code>CryptoParam_t</code> contains the following members:
    </p>

    <p><code>iCryptoObj_t info;</code>
      This member is used when <code>param</code> and <code>aux</code> are
      both <code>NULL</code>, which indicates this parameter is an
      algorithm instance.
    </p>

    <p><code>tCryptoObj_t template;</code>
      This member is used if <code>param</code> or <code>aux</code> is
      non-<code>NULL</code>, which indicates this parameter is an
      algorithm construction that takes further instantiation parameter(s).
    </p>

    <p>
      The members <code>info</code> and <code>template</code> are aliased
      together in a <code>union</code> data structure.
    </p>

    <p><code>const CryptoParam_t *param;</code>
      If used, this is passed as the first argument to <code>template</code>.
      This allows an algorithm construction to be recursively instantiated
      by other algorithm constructions and instances.
    </p>

    <p><code>IntPtr aux</code>
      If used, this is passed as the first argument to <code>template</code>.
      This member allow certain algorithm constructions to be instantiated with
      miscellaneous objects and values and in ways not defined in MySuiteA.
      This member is aliased to <code>param</code> in a <code>union</code>
      data structure, so that caller of <code>template</code> doesn't have to
      be aware of its argument semantics.
    </p>

    <p>
      Both the parameter <code>P</code> and the member <code>param</code> may
      point to both a single <code>CryptoParam_t</code> object, or the initial
      element of an array of which - in the case of an array, the algorithm
      construction is said to be parameterized by multiple elements.
    </p>

    <h2>Consideration for Public-Key Algorithms</h2>

    <p>
      Previously (before v0.2) there was a <code>PKParamsFunc</code> query for
      obtaining instantiation parameters for use in PKC algorithms. The way
      it's implemented caused inflexibility with re-combining PKC Algorithms
      with other instantiation parameters.
    </p>

    <p>
      The approach taken in v0.2 is to have a <code>PKC_Algo_Inst_t</code>
      data structure, representing an PKC algorithm instance, defined as:
    </p>

    <pre>
      typedef struct {
      <span class="tab"></span>int secbits;
      <span class="tab"></span>tCryptoObj_t algo;
      <span class="tab"></span>CryptoParam_t *param;
      } PKC_Algo_Inst_t;
    </pre>

    <p>
      Initial set of instantiation parameters for the algorithms are declared
      in the header files named <code>${algorithm-name}-paramset.h</code>, and
      defined in the corresponding C source code file. Algorithm instances are
      generally named as <code>${Algorithm-Name}_${Parameter}</code>
    </p>

    <p>
      To use an algorithm instance, after checking it provides the desired
      security level, query <code>algo</code> with <code>param</code>
      as instantiation parameter, and obtain relevant algorithm
      characteristics and interfaces.
    </p>

    <h2>Facilities for Supporting Multi-Threaded Algorithms</h2>

    <p>
      Parallel and tree hashing had been an active area of research, with
      results such as KangarooTwelve and BLAKE3 turning up. These 2 algorithms
      are implemented in the Suite with a thin layer of hosted library support.
    </p>

    <p>
      The model chosen for these multi-thread capable algorithms, is to
      implement them in such way that, they can take a parallel object to
      dispatch independent workloads to a crew of threads in a hosted
      environment; equally, in a freestanding environment, the thread crew
      can just be a stub that executes the workload subroutine within the
      control flow with no benefit of any concurrency.
    </p>

    <p>
      The thread crew is provided as a pointer to a structure which contains
      at least 2 interfaces - an <code>enqueue</code> that dispatches the
      workload, and a <code>wait</code> that waits for all currently dispatched
      workloads to complete. The thread crew instances shall have structures
      that're layout-compatible with the <code>TCrew_Abstract_t</code>
      data type, as defined here:
    </p>

    <pre>
      typedef void (*TCrew_Assignment_t)(void *ctx);

      typedef int (*TCrew_Dispatch_t)(
      <span class="tab"></span>void *crew, TCrew_Assignment_t func, void *ctx);

      typedef struct {
      <span class="tab"></span>TCrew_Dispatch_t enqueue;
      <span class="tab"></span>TCrew_Dispatch_t wait;
      } TCrew_Abstract_t;
    </pre>

    <h1>MySuiteA Algorithm APIs</h1>

    <p>
      MySuiteA strives to implement a uniform set of interface where there's
      a common API for each type of cryptographic algorithm. This interface
      is layered, where higher-level schemes may be instantiated from
      lower-level primitives. As explained in the note in "notes.md" dated
      [2021-09-03b], blockciphers, permutations, hash, and XOF functions
      never take parameters to instantiate from, and will always be
      algorithm instances.
    </p>

    <!-- p>
         Some APIs are marked as "low-level". The primitives these APIs
         corresponds to are considered strictly building blocks for
         higher-level constructs and shouldn't be used directly in general.
         For example, a blockcipher shouldn't be used directly to
         encryption information, especially not in a inconsiderate ECB
         mode of operation; it should be used in a mode that provides at least
         IND-CPA such as CBC, CTR, or an authenticated encryption mode that
         provides IND-CCA (and IND-CCA2).
         </p -->

    <p>
      MySuiteA is an octet-oriented implementation, and is written with the
      assumption that 1 byte is exactly 8 bits (1 octet). It also assumes
      that 16-bit, 32-bit, 64-bit exact-width integers are available.
    </p>

    <p>
      In the following sub-sections, property queries available to a particular
      type of cryptographic algorithm are listed in <code>code shading</code>,
      each followed by a description of its semantic. The following shorthands
      are used in function prototype descriptions:
    </p>

    <table>
      <tr><th><code>buf</code></th> <td><code>void *</code></td> </tr>
      <tr><th><code>dat</code></th> <td><code>void const *</code></td> </tr>
      <tr>
        <th><code>rbuf</code></th>
        <td><code>void *restrict</code></td>
      </tr>
      <tr>
        <th><code>rdat</code></th>
        <td><code>void const *restrict</code></td>
      </tr>
      <tr>
        <th><code>_param_</code></th>
        <td><code>const CryptoParam_t *P</code></td>
      </tr>
      <tr>
        <th><code>_tc_</code></th>
        <td><code>TCrew_Abstract_t *restrict tc</code>
    </table>

    <h2>Blockcipher</h2>

    <p>
      A blockcipher is a fixed-width keyed permutation. MySuiteA currently
      only support a single block size of 128 bits. Use of 64-bit blocks
      have negative security implications; blockciphers with larger
      block sizes currently lack support from higher-level algorithm
      constructions and therefore have poorer interoperability and is of
      lesser use.
    </p>

    <p>
      Note the phrase "blockcipher instance" is used to distinguish it from
      a blockcipher family, which may specify many variants of blockcipher
      instances.
    </p>

    <dl>
      <dt><code>blockBytes</code></dt>
      <dd>Block size of the blockcipher instance in bytes</dd>

      <dt><code>keyBytes</code></dt>
      <dd>Key size of the blockcipher instance in bytes</dd>

      <dt><code>keyschedBytes</code></dt>
      <dd>Key schedule size of the blockcipher instance in bytes</dd>

      <dt><code>EncFunc</code></dt>
      <dd>
        The blockcipher encryption function of prototype
        <code>void (*)(dat in, buf out, rdat w);</code> where
        <ul>
          <li><code>in</code> is the input plaintext block, </li>
          <li><code>out</code> is the output ciphertext block, and </li>
          <li><code>w</code> is the key schedule generated from the key. </li>
        </ul>
      </dd>

      <dt><code>DecFunc</code></dt>
      <dd>
        The blockcipher decryption function of prototype
        <code>void (*)(dat in, buf out, rdat w);</code> where
        <ul>
          <li><code>in</code> is the input ciphertext block, </li>
          <li><code>out</code> is the output plaintext block, and </li>
          <li><code>w</code> is the key schedule generated from the key. </li>
        </ul>
      </dd>

      <dt><code>KschdFunc</code></dt>
      <dd>
        The key schedule expansion function of prototype
        <code>void (*)(rdat key, rbuf w);</code> where
        <ul>
          <li><code>key</code> is cipher key to use, </li>
          <li><code>w</code> is the buffer to hold the key schedule. </li>
        </ul>
      </dd>
    </dl>

    <p><em>[note:in-out-ptr-alias]
      Note that neither <code>in</code> nor <code>out</code> has the
      <code>restrict</code> pointer qualifier. This is an intentional
      design decision for allowing in-place cipher computation.
      It is implemented as if the encryption and decryption functions first
      copied input to output buffer before encryption/decryption.
    </em></p>

    <h2>Permutation</h2>

    <dl>
      <dt><code>blockBytes</code></dt>
      <dd>The block size of the permutation</dd>

      <dt><code>PermuteFunc</code></dt>
      <dd>
        The (forward) permutation function of prototype
        <code>void (*)(dat in, buf out);</code> where
        <ul>
          <li><code>in</code> is the input block, </li>
          <li><code>out</code> is the output block. </li>
        </ul>
      </dd>
    </dl>

    <p>
      See note tagged <em>[note:in-out-ptr-alias]</em> in the
      <a>Blockcipher</a> section.
    </p>

    <h2>Hash Function & Message Authentication Code</h2>

    <dl>
      <dt><code>outBytes</code></dt>
      <dd>The length of the hash digest / MAC tag output in bytes</dd>

      <dt><code>blockBytes</code> (hash-specific)</dt>
      <dd>
        The amount of data in bytes, which when accumulated, will cause the
        state transformation function, (be it a compression function,
        a permutation, or anything else,) to iterate for 1 invocation.
      </dd>

      <dt><code>keyBytes</code> (MAC-specific)</dt>
      <dd>
        The supported length(s) of the key. See "mysuitea-common.h" for
        the interpretation of the values of this property.
      </dd>

      <dt><code>contextBytes</code></dt>
      <dd>
        The size of the working context, in bytes,
        for the hash/MAC function.
      </dd>

      <dt><code>InitFunc</code> (hash-specific)</dt>
      <dd>
        The working context initialization function of prototype
        <code>void (*)(rbuf x);</code> where
        <ul>
          <li>
            <code>x</code> is the pointer
            to the working context in memory.
          </li>
        </ul>
      </dd>

      <dt><code>KInitFunc</code> (MAC-specific)</dt>
      <dd>
        The working context initialization function of prototype
        <code>void *(*)(rbuf x, rdat k, size_t klen);</code>;
        or if the construction is parameterized, the function of prototype
        <code>void *(*)(_param_, rbuf x, rdat k, size_t klen);</code> where
        <ul>
          <li><code>_param_</code> is the instantiation parameter, </li>
          <li>
            <code>x</code> is the pointer,
            to the working context in memory.
          </li>
          <li><code>k</code> is MAC key to use, </li>
          <li><code>klen</code> is length of the key input. </li>
        </ul>
        If the key length is invalid for the MAC function, or some other
        (yet-to-be-specified) error occurs, the function returns
        <code>NULL</code>. Otherwise, everything succeeds, and
        <code>x</code> is returned.
      </dd>

      <dt><code>UpdateFunc</code></dt>
      <dd>
        The update function that feeds data into the hash working context.
        It has the prototype
        <code>void (*)(rbuf x, rdat data, size_t len);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context, </li>
          <li><code>data</code> the data to feed into the working context,</li>
          <li><code>len</code> the length of the data. </li>
        </ul>
      </dd>

      <dt><code>FinalFunc</code></dt>
      <dd>
        The finalization function which marks the working context as finalized
        and computes the hash digest / MAC tag if the working context hasn't
        been finalized yet, and then reads out the result. It has the prototype
        <code>void (*)(rbuf x, rdat out, size_t t);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context, </li>
          <li><code>out</code>
            is the pointer to the memory location to which,
            the hash digest will be written,
          </li>
          <li><code>len</code>
            is the requested length of the digest.
            <em></em>
          </li>
        </ul>
      </dd>
    </dl>

    <p><em>
      [note:outlen]: It is a convention of MySuiteA that,
      if the requested length is greater than (or less than) the
      digest/tag length of the hash/MAC function, then the output will be
      zero-extended (or truncated).
    </em></p>

    <p>Additionally, for parallel and tree hashing algorithms, there are:</p>

    <dl>
      <dt><code>Update4Func</code></dt>
      <dd>
        The multi-threaded update function. In addition to the arguments taken
        by the regular update function, it takes a parallel object that's
        layout compatible with <code>TCrew_Abstract_t</code> to potentially
        provide concurrent computation. It has the prototype
        <code>void (*)(rbuf x, rdat data, size_t len, _tc_);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context,</li>
          <li><code>data</code> the data to feed into the working context,</li>
          <li><code>len</code> the length of the data, and</li>
          <li><code>tc</code>
            the thread crew that will receive the dispatched workload.</li>
        </ul>
      </dd>

      <dt><code>Final2Func</code></dt>
      <dd>
        The finalization function which marks the working context as
        finalized and perform some tail computation. It has the prototype
        <code>void (*)(rbuf x, _tc_);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context,</li>
          <li><code>tc</code>
            the thread crew that had been used with the working context.</li>
        </ul>
      </dd>

      <dt><code>Read4Func</code></dt>
      <dd>
        The reading function that copies the digest into output buffers.
        It has prototype
        <code>void (*)(rbuf x, rbuf data, size_t len, int flags);</code>
        where
        <ul>
          <li><code>x</code> is the pointer to the working context,</li>
          <li><code>data</code> is the pointer to the output buffer,</li>
          <li><code>len</code> is the length of digest data to retrieve,</li>
          <li><code>flags</code> specifies miscellaneous information.
        </ul>
        <p>
          Because newer parallel and tree hashing algorithms are commonly
          XOFs, by default, this function behaves identically to XOF's
          <code>ReadFunc</code> when <code>flags</code> is 0. There is the flag
          <code>HASHING_READ4_REWIND</code> that resets the reading offset
          of the hashing context to the start, and it's currently the only flag
          defined for <code>Read4Func</code>.
      </dd>
    </dl>

    <h2>XOF (Extendable-Output Function)</h2>

    <dl>
      <dt><code>outTruncBytes</code></dt>
      <dd>
        The recommended output length if this XOF is to be used as a
        regular hash function. This generally matches the length needed
        to achieve collision-resistance at the security level advertised
        by the algorithm.
      </dd>

      <dt><code>blockBytes</code> (hash-specific)</dt>
      <dd>
        The amount of data in bytes, which when accumulated, will cause the
        state transformation function, (be it a compression function,
        a permutation, or anything else,) to iterate for 1 invocation.
      </dd>

      <dt><code>contextBytes</code></dt>
      <dd>
        The size of the working context, in bytes,
        for the XOF function.
      </dd>

      <dt><code>InitFunc</code> (hash-specific)</dt>
      <dd>
        The working context initialization function of prototype
        <code>void (*)(rbuf x);</code> where
        <ul>
          <li>
            <code>x</code> is the pointer
            to the working context in memory.
          </li>
        </ul>
      </dd>

      <dt><code>WriteFunc</code></dt>
      <dd>
        The update function that feeds (writes) data into the
        XOF working context. It has the prototype
        <code>void (*)(rbuf x, rdat data, size_t len);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context, </li>
          <li><code>data</code> the data to feed into the working context,</li>
          <li><code>len</code> the length of the data. </li>
        </ul>
      </dd>

      <dt><code>XofFinalFunc</code></dt>
      <dd>
        The finalization function. If the working context hasn't been
        finalized yet, marks the working context as finalized and performs
        finalization computation to make the context ready for output being
        read. Otherwise, it resets output stream to the start.
        It has the prototype
        <code>void (*)(rbuf x);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context, </li>
        </ul>
      </dd>

      <dt><code>ReadFunc</code></dt>
      <dd>
        The output function that reads data out of the XOF working context.
        It has the prototype
        <code>void (*)(rbuf x, rbuf data, size_t len);</code> where
        <ul>
          <li><code>x</code> is the pointer to the working context, </li>
          <li><code>data</code> the buffer into which data will be read, </li>
          <li><code>len</code> the requested length of the data. </li>
        </ul>
      </dd>
    </dl>

    <p>
      Because <code>WriteFunc</code> and <code>UpdateFunc</code> have
      identical prototype, and that they serve very similar purpose,
      these 2 symbolic constants are aliased together by having
      identical numerical value.
    </p>

    <p>
      Some algorithms (e.g. KMAC) can operate in both XOF and regular
      fixed-length mode, and may support domain separation between different
      usage. These algorithms usually support all three of
      <code>FinalFunc</code>,
      <code>XofFinalFunc</code>, and
      <code>ReadFunc</code>.
      And, their <code>FinalFunc</code> behave similar to
      <code>XofFinalFunc</code> and <code>ReadFunc</code> called in
      adjacent sequence.
    </p>

    <h2>Encryption</h2>

    <dl>
      <dt><code>keyBytes</code></dt>
      <dd>The byte length of the key supported by the algorithm instance</dd>

      <dt><code>contextBytes</code></dt>
      <dd>The size of the cipher working context in bytes</dd>

      <dt><code>ivBytes</code></dt>
      <dd>
        The byte length of the initialization vector
        supported by the algorithm instance.
      </dd>

      <dt><code>KInitFunc</code></dt>
      <dd>
        The working context initialization function of prototype
        <code>void *(*)(rbuf x, rdat k, size_t klen);</code>;
        or if it's a parameterized algorithm construction,
        the function of prototype
        <code>void *(*)(_param_, rbuf x, rdat k, size_t klen);</code> where
        <ul>
          <li><code>_param_</code> is the instantiation parameter, </li>
          <li>
            <code>x</code> is the pointer
            to the working context in memory,
          </li>
          <li><code>k</code> is cipher key to use, </li>
          <li><code>klen</code> is length of the key input. </li>
        </ul>
        If the key length is invalid for the algorithm instance, or some other
        (yet-to-be-specified) error occurs, the function returns
        <code>NULL</code>. Otherwise, everything succeeds, and
        <code>x</code> is returned.
      </dd>

      <dt><code>AEncFunc</code></dt>
      <dd>
        The authenticated encryption function of prototype
        <pre>void *(*)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>size_t ivlen, dat iv,
          <span class="tab"></span>size_t alen, dat aad,
          <span class="tab"></span>size_t len, dat in, buf out,
          <span class="tab"></span>size_t tlen, buf T);
        </pre> where
        <ul>
          <li><code>x</code> is the cipher working context, </li>
          <li><code>ivlen</code> is the byte length of <code>iv</code>, </li>
          <li><code>iv</code> points to the initialization vector, </li>
          <li><code>alen</code> is the byte length of <code>aad</code>, </li>
          <li><code>aad</code>
            is the additional data to be authenticated but not encrypted,
          </li>
          <li><code>len</code>
            is the byte length of plaintext and ciphertext,
          </li>
          <li><code>in</code>, <code>out</code>
            are plaintext input and ciphertext output respectively,
          </li>
          <li><code>tlen</code>
            is the requested length of the tag,
          </li>
          <li><code>T</code>
            is the buffer in which the tag will be stored.
          </li>
        </ul>
        Upon successful encryption, <code>out</code> will be returned.
        Otherwise, if there's unsupported/invalid parameter(s) or
        any other kind of error, <code>NULL</code> will be returned.
      </dd>

      <dt><code>ADecFunc</code></dt>
      <dd>
        The authenticated encryption function of prototype
        <pre>void *(*)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>size_t ivlen, dat iv,
          <span class="tab"></span>size_t alen, dat aad,
          <span class="tab"></span>size_t len, dat in, buf out,
          <span class="tab"></span>size_t tlen, dat T);
        </pre> where
        <ul>
          <li><code>x</code> is the cipher working context, </li>
          <li><code>ivlen</code> is the byte length of <code>iv</code>, </li>
          <li><code>iv</code> points to the initialization vector, </li>
          <li><code>alen</code> is the byte length of <code>aad</code>, </li>
          <li><code>aad</code>
            is the additional non-encrypted data to be verified,
          </li>
          <li><code>len</code>
            is the byte length of plaintext and ciphertext,
          </li>
          <li><code>in</code>, <code>out</code>
            are ciphertext input and plaintext output respectively,
          </li>
          <li><code>tlen</code>
            is the length of the MAC tag to be compared,
            which may be truncated or zero-extended
            at the request of the invoker of the encryption function,
          </li>
          <li><code>T</code>
            is the buffer that stores the MAC tag.
          </li>
        </ul>
        Upon successful decryption, <code>out</code> will be returned.
        Otherwise, if there's decryption failure, unsupported/invalid
        parameter(s) or any other kind of error, <code>NULL</code>
        will be returned.
      </dd>
    </dl>

    <p>
      See notes tagged <em>[note:in-out-ptr-alias]</em> in the
      <a>Blockcipher</a> section and <em>[note:outlen]</em> in the
      <a>Hash Function & Message Authentication Code</a> section.
    </p>

    <h2>Pseudo-Random Number Generator</h2>

    <dl>
      <dt><code>contextBytes</code></dt>
      <dd>The size of the PRNG working context in bytes. </dd>

      <dt><code>seedBytes</code></dt>
      <dd>The supported length(s) of the seed in bytes. </dd>

      <dt><code>InstInitFunc</code></dt>
      <dd>
        The PRNG instantiation initialization function. It has the prototype:
        <code>void *(*)(rbuf x, rdat seedstr, size_t len);</code> or
        if the construction is parameterized, the function of prototype:
        <code>void *(*)(_param_, rbuf x, rdat seedstr, size_t len);</code>
        where
        <ul>
          <li><code>_param_</code> is the instantiation parameter, </li>
          <li><code>x</code> is the pointer to the working context, </li>
          <li><code>seedstr</code> is the pointer to the PRNG seed, </li>
          <li><code>len</code> is the length of the seed in bytes, </li>
        </ul>
        If the seed length is unsupported, or some other (yet-to-be-speciied)
        error, the function returns <code>NULL</code>. Otherwise, everything
        succeeds, and <code>x</code> is returned.
      </dd>

      <dt><code>ReseedFunc</code></dt>
      <dd>
        The PRNG reseeding function of prototype:
        <code>void (*)(rbuf x, rdat seedstr, size_t len);</code> where
        <ul>
          <li><code>x</code> is the pointer to the PRNG working context, </li>
          <li><code>seedstr</code>
            is the pointer to the reseeding material,
          </li>
          <li><code>len</code>
            is the length of the reseeding material in bytes.
          </li>
        </ul>
      </dd>

      <dt><code>GenFunc</code></dt>
      <dd>
        The PRNG randomness generation function of prototype:
        <code>void (*)(rbuf x, rbuf out, size_t len);</code> where
        <ul>
          <li><code>x</code> is the pointer to the PRNG working context, </li>
          <li><code>seedstr</code>
            is the pointer to the memory location to store the random bytes,
          </li>
          <li><code>len</code>
            is the length of the requested random bytes.
          </li>
        </ul>
      </dd>
    </dl>

    <p>
      Due to functional similarity as well as them having
      identical prototypes,
      <code>InstInitFunc</code>,
      <code>ReseedFunc</code>, and
      <code>GenFunc</code>
      are aliased to
      <code>KInitFunc</code>,
      <code>WriteFunc</code>, and
      <code>ReadFunc</code> respectively, by them having
      identical corresponding numerical values.
    </p>

    <h2>Key-Pair Encoding/Decoding Function Set</h2>

    <p>
      The API for key-pair encoding and decoding is common to both PKE/KEM
      and signature schemes, therefore it's described here in the first place.
    </p>

    <p>The encoder functions have the prototype:</p>
    <pre>IntPtr (*PKKeyEncoder_t)(
      <span class="tab"></span>rdat any,
      <span class="tab"></span>rbuf enc,
      <span class="tab"></span>size_t enclen,
      <span class="tab"></span>_param_);</pre>

    <p>where as the decoder functions have the prototype:</p>
    <pre>IntPtr (*PKKeyDecoder_t)(
      <span class="tab"></span>rbuf any,
      <span class="tab"></span>rdat enc,
      <span class="tab"></span>size_t enclen,
      <span class="tab"></span>_param_);</pre>

    <p>
      The <code>any</code> parameter points to the working context of the
      PKC algorithm, which may be the public-key or the private-key
      working context depending on the usage. The <code>enc</code> parameter
      points to the buffer that holds the encoded key. The <code>enclen</code>
      specifies the length of this buffer. The <code>_param_</code> parameter
      specifies the instantiation parameters used for the algorithm, which will
      be taken into account when estimating the size of the working context.
    </p>

    <p>
      These functions have 2 passes. In the 1st pass, these functions returns
      the estimated size of encoded key (encoder) or the working context
      (decoder). If some error occurs, then -1 is returned. The actual
      encoding/decoding is carried out in the 2nd pass. The return value in the
      2nd pass is the same as that from the 1st pass.
    </p>

    <p>
      Such setup is necessary, as some key formats (e.g. ASN.1 DER encoding of
      RSA private keys) have variable encoded lengths depending on the values
      of components of the key material, even when the parameters are otherwise
      constant.
    </p>

    <p>
      In pass 1, the <code>enc</code> and <code>enclen</code> should be
      specified as <code>NULL</code> and 0 respectively for the encoder
      (although <code>enclen</code> is ignored for now, it may have other
      reserved meaning in future versions of MySuiteA); for the decoder,
      <code>any</code> should be specified as <code>NULL</code>.
    </p>

    <p>
      In pass 2, all of <code>any</code>, <code>enc</code>,
      <code>enclen</code>, and <code>_param_</code> should be specified with
      valid values.
    </p>

    <dl>
      <dt><code>PKKengenFunc</code></dt>
      <dd>
        The key generation function with which this key-pair formatting
        function set is associated.
      </dd>
      <dt><code>PKPrivkeyEncoder</code></dt>
      <dd>
        <code>PKKeyEncoder_t</code> where <code>any</code>
        is the private-key working context
      </dd>
      <dt><code>PKPrivkeyDecoder</code></dt>
      <dd>
        <code>PKKeyDecoder_t</code> where <code>any</code>
        is the private-key working context
      </dd>
      <dt><code>PKPubkeyExporter</code></dt>
      <dd>
        <code>PKKeyEncoder_t</code> where <code>any</code>
        is the private-key working context
      </dd>
      <dt><code>PKPubkeyEncoder</code></dt>
      <dd>
        <code>PKKeyEncoder_t</code> where <code>any</code>
        is the public-key working context
      </dd>
      <dt><code>PKPubkeyDecoder</code></dt>
      <dd>
        <code>PKKeyDecoder_t</code> where <code>any</code>
        is the public-key working context
      </dd>
    </dl>

    <h2>Ciphergram Encoding/Decoding Function Set</h2>

    <p>
      The interface for encoding and decoding is the same for both KEM/PKE
      and digital signatures. They're associated with the PKC algorithm
      through the public/private function pair.
    </p>

    <p>The encoder functions have the prototype:</p>
    <pre>void *(*PKCiphergramEncoder_t)(
      <span class="tab"></span>rbuf x,
      <span class="tab"></span>rbuf c, size_t *len);</pre>

    <p>
      The encoder function saves the ciphergram (ciphertext or signature)
      into <code>c</code>. It returns <code>c</code> on success and
      <code>NULL</code> otherwise. If <code>c</code> is <code>NULL</code>
      then <code>*len</code> is set to its length.
    </p>

    <p>
      Such set up is necessary as some formats of some signatures (e.g. ECDSA
      when encoding (r,s) using ASN.1 DER encoding, or the Falcon PQC digital
      signature scheme) have lengths that're variable.
    </p>

    <p>The decoder functions have the prototype:</p>
    <pre>void *(*PKCiphergramDecoder_t)(
      <span class="tab"></span>rbuf x,
      <span class="tab"></span>rdat c, size_t len);</pre>

    <p>
      The decoder function loads the ciphergram into the working context of
      the PKC algorithm. It returns <code>x</code> on success and
      <code>NULL</code> on failure.
    </p>

    <dl>
      <dt><code>PKEncFunc</code> (KEM-specific)</dt>
      <dd>The key encapsulating function with which the
        ciphergram formatting function set is associated,</dd>

      <dt><code>PKDecFunc</code> (KEM-specific)</dt>
      <dd>The key decapsulating function with which the
        ciphergram formatting function set is associated,</dd>

      <dt><code>PKSignFunc</code> (signature scheme -specific)</dt>
      <dd>The private-key signing function with which the
        ciphergram formatting function set is associated,</dd>

      <dt><code>PKVerifyFunc</code> (signature scheme -specific)</dt>
      <dd>The public-key verification function with which the
        ciphergram formatting function set is associated,</dd>

      <dt><code>PKCtEncoder</code></dt>
      <dd>The ciphergram encoding function of prototype
        <code>PKCiphergramEncoder_t</code>.
        <code>Ct</code> means cipher transcript.</dd>

      <dt><code>PKCtDecoder</code></dt>
      <dd>The ciphergram decoding function of prototype
        <code>PKCiphergramDecoder_t</code>.
        <code>Ct</code> means cipher transcript.</dd>
    </dl>

    <h2>KEM - Key Encapsulation Mechanisms</h2>

    <dl>
      <dt><p><code>isParamDetermByKey</code></p></dt>
      <dd>
        <p>
          If the value of this query is 1, then the values of the queries
          <code>bytesCtxPriv</code> and <code>bytesCtxPub</code> can only
          be used for private contexts for generating keys, as the parameters
          and the size of the working contexts are variable depending on the
          key to be loaded.
        </p>
        <p>
          On the other hand, if the value of this query is 0, then
          <code>bytesCtxPriv</code> and <code>bytesCtxPub</code> can be
          used to set parameters for the working context, as they're not
          determined by the key. See "mysuitea-common.h" for more.
        </p>
      </dd>

      <dt><code>bytesCtxPriv</code></dt>
      <dd>The size of the private-key working context</dd>
      <dt><code>bytesCtxPub</code></dt>
      <dd>The size of the public-key working context</dd>

      <!-- dt><p><code>PKParamsFunc</code></p></dt>
           <dd>
           <p>
           The parameter sets used for instantiating PKC algorithms are
           more complex than that for symmetric-key algorithms. This is why
           a function that can be queried of default, or recommended set of
           parameters is needed.
           </p>
           <p>
           Such function is of prototype:
           <code>int (*PKParamsFunc_t)(int index, CryptoParam_t *out);</code>.
           </p>
           <p>
           When <code>index</code> is 0, the vector length of <code>out</code>
           is returned. This is the number of <code>CryptoParam_t</code>
           objects that needs to be allocated for <code>out</code>.
           </p>
           <p>
           Each successive values of <code>index</code> returns a parameter set
           in the parameter vector pointed to by <code>out</code> and the
           estimated strength of security in bits in the return value.
           The actual linking structure of <code>out</code> written by the
           function may not necessarily be linear. When there's no more
           parameter presets available, 0 is returned.
           </p>
           </dd -->

      <dt><p><code>PKKeygenFunc</code></p></dt>
      <dd>
        <p>The key generation function of prototype:</p>
        <pre>IntPtr (*PKKeygenFunc_t)(
          <span class="tab"></span>rbuf x, _param_,
          <span class="tab"></span>GenFunc_t prng_gen, rbuf prng);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the private-key working context,</li>
          <li><code>_param_</code> specifies the parameter
            for generating the new key,</li>
          <li><code>prng_gen</code> is the PRNG
            random bits generating function,</li>
          <li><code>prng</code> is the working context for the PRNG.</li>
        </ul>
        <p>
          This function generates a key-pair and save its internal
          representation in the working context, which can be retrieved using
          key encoder/exporter functions and loaded using decoder functions.
        </p>
        <p>
          If <code>x</code> is <code>NULL</code>, then then function returns
          the estimated space needed for allocating a working context based on
          the given parameters; otherwise, <code>x</code> is returned.
        </p>
      </dd>

      <dt><p><code>PKEncFunc</code></p></dt>
      <dd>
        <p>The KEM secret encapsulation function of prototype:</p>
        <pre>void *(*PKEncFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>rbuf ss, size_t *restrict sslen,
          <span class="tab"></span>GenFunc_t prng_gen, rbuf prng);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the public-key working context,</li>
          <li><code>ss</code> points to the buffer that will
            receives the shared secret,</li>
          <li>
            <code>sslen</code> points to a variable of type
            <code>size_t</code>. If <code>ss</code> is <code>NULL</code>,
            this variable will be set to the length of the shared secret.
            If <code>ss</code> is non-<code>NULL</code>, the variable
            indicates the size of the buffer pointed to by <code>ss</code>,
            in which case, at most <code>*sslen</code> bytes will be written
            to <code>ss</code>, and if there's excess space than needed to
            store the shared secret, the result will be right-padded with
            nul bytes.
          </li>
          <li><code>prng_gen</code> is the PRNG
            random bits generating function,</li>
          <li><code>prng</code> is the working context for the PRNG.</li>
        </ul>
        <p>
          This function generates a shared secret and a ciphertext based on
          the public key loaded into the public-key working context.
          The shared secret is stored into <code>ss</code> while the ciphertext
          is saved in a internal representation in the working context and
          will be exported using a ciphergram encoding function.
        </p>
      </dd>

      <dt><p><code>PKDecFunc</code></p></dt>
      <dd>
        <p>The KEM secret decapsulation function of prototype:</p>
        <pre>void *(*PKDecFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>rbuf ss, size_t *restrict sslen);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the private-key working context,</li>
          <li><code>ss</code> points to the buffer that will
            receives the shared secret,</li>
          <li>
            <code>sslen</code> points to a variable of type
            <code>size_t</code>. If <code>ss</code> is <code>NULL</code>,
            this variable will be set to the length of the shared secret.
            If <code>ss</code> is non-<code>NULL</code>, the variable
            indicates the size of the buffer pointed to by <code>ss</code>,
            in which case, at most <code>*sslen</code> bytes will be written
            to <code>ss</code>, and if there's excess space than needed to
            store the shared secret, the result will be right-padded with
            nul bytes.
          </li>
        </ul>
        <p>
          This function decapsulates the shared secret from the ciphertext
          using the private key. The ciphertext and the private key are loaded
          into the private-key working context using the private key decoder
          function and the ciphertext decoder function.
          For some cryptosystems, the ciphertext may be of variable length
          (e.g. RSA PKE), as such, repeating the call returns the same
          information unless a different ciphertext is loaded using the
          ciphergram decoder function.
        </p>
      </dd>
    </dl>

    <h2>DSS - Digital Signature Schemes</h2>

    <dl>
      <dt><code>isParamDetermByKey</code></dt>
      <dt><code>bytesCtxPriv</code></dt>
      <dt><code>bytesCtxPub</code></dt>
      <!-- dt><code>PKParamsFunc</code></dt -->
      <dt><code>PKKeygenFunc</code></dt>
      <dd><p>Same as that for KEMs'.</p></dd>

      <dt><code>dssNonceNeeded</code></dt>
      <dd>A boolean indicating whether the scheme uses nonce</dd>

      <dt><code>dssExternRngNeededForNonce</code></dt>
      <dd>If the <em>implementation</em> of the algorithm is capable of
        generating nonce independently of the RNG parameters, then
        this is <code>false</code>, otherwise <code>true</code>.</dd>

      <dt><p><code>PKSignFunc</code></p></dt>
      <dd>
        <p>The digital signature signing function of prototype:</p>
        <pre>void *(*PKSignFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>rdat msg, size_t msglen,
          <span class="tab"></span>GenFunc_t prng_gen, rbuf prng);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the private-key working context,</li>
          <li><code>msg</code> is the buffer
            holding the message to be signed,</li>
          <li><code>msglen</code> is the length of the message in bytes,</li>
          <li><code>prng_gen</code> is the PRNG
            random bits generating function,</li>
          <li><code>prng</code> is the working context for the PRNG.</li>
        </ul>
        <p>
          The function signs the message <code>msg</code> and saves the
          internal representation of the signature in <code>x</code> to be
          exported using the ciphergram encoding function. It returns
          <code>x</code> on success and <code>NULL</code> on failure.
        </p>
      </dd>

      <dt><p><code>PKVerifyFunc</code></p></dt>
      <dd>
        <p>The digital signature signing function of prototype:</p>
        <pre>const void *(*PKVerifyFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>rdat msg, size_t msglen);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the public-key working context,</li>
          <li><code>msg</code> is the buffer
            holding the message to be verified,</li>
          <li><code>msglen</code> is the length of the message in bytes,</li>
        </ul>
        <p>
          The function verifies the message <code>msg</code> with the
          public key and the signature loaded into the public-key working
          context using the public-key and ciphergram decoder function.
          It returns <code>msg</code> if signature is valid, and
          <code>NULL</code> otherwise.
        </p>
      </dd>
    </dl>

    <h3>Incremental Signing / Pre-Hashing</h3>

    <p>
      Many existing digital signature schemes actually signs a hash digest
      of the message. Those that does this including RSA (PKCS#1 v1.5 and PSS),
      ECDSA, and some variants of EdDSA specified in RFC-8032. To realize their
      full potential, incremental signing are devised.
    </p>

    <dl>
      <dt><code>dssPreHashingType</code></dt>
      <dd>
        <p>
          The type of pre-hashing supported by the algorithm <em>instance</em>.
          It can be one of the following enumerations:
        </p>
        <ul>
          <li><code>dssPreHashing_Unsupported</code>:
            This algorithm does not support pre-hashing at all.</li>

          <li><code>dssPreHashing_Interface</code>:
            PrePre-hashing offered in an interface, and the algorithm behaves
            the same as if the message is buffered and signed all-at-once.</li>

          <li><code>dssPreHashing_Variant</code>:
            Pre-hashing offered in an interface, but algorithm will behave
            differently from that of buffering and signing all-at-once.</li>

          <li><code>dssPreHashing_ParamSet</code>:
            Pre-hashing is supported in a separate algorithm instance.</li>
        </ul>
        <p></p>
      </dd>

      <dt><code>PKIncSignInitFunc</code></dt>
      <dt><code>PKIncVerifyInitFunc</code></dt>
      <dd>
        <p>
          The initialization functions for incremental signing and
          incremental verifying. They have the prototype:
        </p>
        <pre>void *(*PKIncSignInitFunc_t)(rbuf x, UpdateFunc_t *placeback);
        </pre>
        <p>This type has an alias: <code>PKIncVerifyInitFunc_t</code>.</p>
        <p>
          When called, it initializes a hashing context and prepare it
          with algorithm-specific prefix data. Before returning the pointer
          to this working context, it places a pointer to the update function
          of this hashing function into placeback.
        </p>
      </dd>

      <dt><code>PKIncSignFinalFunc</code></dt>
      <dd>
        <p>
          The function that completes hashing of and produce a signature
          for the hashed message, of the prototype:
        </p>
        <pre>void *(*PKIncSignFinalFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>GenFunc_t prng_gen, rbuf prng);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the private-key working context,</li>
          <li><code>prng_gen</code> is the PRNG
            random bits generating function,</li>
          <li><code>prng</code> is the working context for the PRNG.</li>
        </ul>
      </dd>

      <dt><code>PKIncVerifyFinalFunc</code></dt>
      <dd>
        <p>
          The function that completes hashing and verifies the signature
          of the hashed message, of the prototype:
        </p>
        <pre>void *(*PKIncVerifyFinalFunc_t)(rbuf x);</pre>
        <p>where:</p>
        <ul>
          <li><code>x</code> points to the public-key working context,</li>
        </ul>
      </dd>
    </dl>

    <h2>Miscellaneous Context Control Function</h2>

    <p>
      Context control functions are a class of catch-all functions that
      performs operations that're <em>algorithm-specific</em>.
      Generally, these operations involve additional parameters that
      can't be passed using other uniform APIs.
    </p>

    <dl>
      <dt><code>XctrlFunc</code></dt>
      <dt><code>PubXctrlFunc</code></dt>
      <dt><code>PrivXctrlFunc</code></dt>
      <dd>
        <p>The context control function of prototype:</p>
        <pre>void *(*XctrlFunc_t)(
          <span class="tab"></span>rbuf x,
          <span class="tab"></span>int cmd,
          <span class="tab"></span>const bufvec_t *restrict bufvec,
          <span class="tab"></span>int veclen,
          <span class="tab"></span>int flags);</pre>

        <p>where:</p>
        <ul>
          <li><code>x</code> points to the
            working context of the algorithm,</li>
          <li><code>cmd</code> specifies the sub-function to perform,</li>
          <li><code>bufvec</code> is the array of data buffer elements
            passed to the sub-function</li>
          <li><code>veclen</code> specifies the length of the array,</li>
          <li><code>flags</code> specifies additional information
            for the sub-function, with 0 as a reserved default,</li>
        </ul>

        <p>
          The query <code>XctrlFunc</code> generally apply to symmetric-key
          algorithms,
          whereas <code>PubXctrlFunc</code> and <code>PrivXctrlFunc</code>
          apply to the public and private working contexts of the
          asymmetric-key algorithm. And the type definition for
          <code>bufvec_t</code> is:
        </p>

        <pre>typedef struct {
          <span class="tab"></span>union {
          <span class="tab"></span><span class="tab"></span>size_t len;
          <span class="tab"></span><span class="tab"></span>IntPtr info;
          <span class="tab"></span>};
          <span class="tab"></span>union {
          <span class="tab"></span><span class="tab"></span>void const *dat;
          <span class="tab"></span><span class="tab"></span>void *buf;
          <span class="tab"></span>};
        } bufvec_t;</pre>
      </dd>
    </dl>

  </body>
</html>
